2021-03-15 18:53:54 GMT -05:00
En (Grolemund and Wickham 2019, Cap 14) aprenderás a:
El concepto de expresiones regulares (o regex) para describir patrones de caractéres y de esa manera manipularlos
Manejar las principales funciones del stringr para manipular cadenas de caracteres bajo el marco del tidyverse
\ es el caracter de escape dentro de una cadenastring3 <- "\\\nHola cómo estas\tAntes señalo un tab\nPuedo también señalar \\n"
# Para visualizar la cadena de caracteres
writeLines(string3)## \
## Hola cómo estas Antes señalo un tab
## Puedo también señalar \n
Para la lista completa de caracteres aparte de \n y \t en la consola ejecutar lo siguiente:
?'"' o ?"'"## [1] 62
#\t no es lo mismo que " "
# por eso tenemos como resultado 54
# y no 52
str_length(string3) - str_count(string = string3, pattern = " ")## [1] 54
## [1] "abc"
# se puede utilizar el argumento sep para
# separar la combinación de caracteres
str_c("a", "b", "c", sep = ",")## [1] "a,b,c"
Los valores NA pueden generar problemas.
str_replace_na## [1] NA
# En este parte se puede utilizar el argumento
# collapse dado que los caracteres están
# concatenados
str_replace_na(c("a", NA, "c")) %>% str_c(collapse = ",")## [1] "a,NA,c"
str_c es una función vectorizada## [1] "Letter: a" "Letter: b" "Letter: c" "Letter: d" "Letter: e" "Letter: f"
## [7] "Letter: g" "Letter: h" "Letter: i" "Letter: j" "Letter: k" "Letter: l"
## [13] "Letter: m" "Letter: n" "Letter: o" "Letter: p" "Letter: q" "Letter: r"
## [19] "Letter: s" "Letter: t" "Letter: u" "Letter: v" "Letter: w" "Letter: x"
## [25] "Letter: y" "Letter: z"
animales <- c("abeja", "águila", "araña",
"ballena", "bisonte", "búfalo",
"caballo", "camello", "canario")
str_sub(string = animales, start = 2, end = 4)## [1] "bej" "gui" "rañ" "all" "iso" "úfa" "aba" "ame" "ana"
## [1] "" "a" "" "na" "te" "o" "lo" "lo" "io"
Algunas funciones del paquete stringr tienen la opción de locales:
## [1] "I" "I"
# Se requiere cambiar el locale
# consultar el código de los idiomas en
# https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
str_to_upper(c("i", "ı"), locale = "tr")## [1] "İ" "I"
Otro ejemplo se da en la ordenación de las cadenas de caracteres
## [1] "arándano" "banana" "espinaca"
## [1] "arándano" "espinaca" "banana"
Las expresiones regulares son un forma de describir patrones en cadenas de caracteres.
stringr::str_view y stringr::str_view_all para visualizar los patrones que se buscan describir en las cadenas de caracteres.. representa cualquier caracter excepto un salto de línea. y el caracter .Para diferenciar el metacaracter . y el caracter . inicialmente podemos utilizar \. para señalar que es un caracter y no un metacaracter.
\. pero en las cadenas de caracteres \ también se utiliza para señalar un comportamiento especial como por ejemplo en \n
"\\.". y el caracter .Ahora incluyamos \\.
. y el caracter .A partir de la versión R 4.0.0 podemos utilizar también r"(...)"
help(Quotes) > Character constants\ y el caracter \De nuevo en esta parte debemos pensar como buscar coincidencias de \ en una cadena de caracteres
Creamos primero la expresión regular \\
Ahora necesitamos indicar en la cadena de caracteres que \ no es un metacaracter
\\\\## a\b
\ y el caracter \r"(...)"## a\b
Se puede anclar una expresión regular para que solo busque coincidencias al inicio o al final dado que por defecto se busca en toda la cadena de caracteres
^ para buscar la coincidencia al inicio de la cadena.Se puede anclar una expresión regular para que solo busque coincidencias al inicio o al final dado que por defecto se busca en toda la cadena de caracteres
$ para buscar la coincidencia al final de la cadena.^ y $\bOtros patrones especiales que pueden ser de ayuda
\d: coincide con cualquier dígito.\s: coincide con cualquier espacio en blanco (por ejemplo, espacio simple, tabulador, salto de línea).[abc]: coincide con a, b o c.[^abc]: coincide con todo menos con a, b o c.(a|b): coincide con a o b (disyunción)Para buscar coincidencias respecto a repeticiones se utilizan los siguientes metacaracteres:
?: 0 o 1+: 1 o más*: 0 o másEjemplo con ?
Ejemplo con +
Ejemplo con *
También es posible especificar el número de coincidencias que se quieren encontrar de manera precisa:
{n}: exactamente n{n,}: n o más{,m}: no más de m (pendiente no funciona){n,m}: entre n y mTambién es posible especificar el número de coincidencias que se quieren encontrar de manera precisa:
{n}: exactamente n{n,}: n o más{,m}: no más de m (pendiente no funciona){n,m}: entre n y m{n}, {n,}, {,m} o {n,m} son “avaras” (greedy) ya que tratarán de coincidir con la cadena más larga posible.
Los paréntesis también sirven para crear un grupo de captura y si se acompañan con una numeración me puedo referir nuevamente al grupo capturado
Por ejemplo, la siguiente expresión regular busca todas las frutas que tengan un par de letras repetido.
(..) como \1\2, \3, … pero en este caso solo tengo unoCon el conocimiento básico del lenguaje de expresiones regulares y un conjunto de caracteres es posible utilizar el paquete stringr para:
Una referencia rápida para consultar las funciones de stringr es:
tidyverse la combinación más usual es utilizar dplyr::filter y stringr::str_detectgapminder::gapminder %>%
# Buscar todos los países que empicen por C o c
# como primer caracter y luego como segundo
# caracter por o
filter(str_detect(string = country, pattern = "^[Cc]o"),
year == max(year))## # A tibble: 6 x 6
## country continent year lifeExp pop gdpPercap
## <fct> <fct> <int> <dbl> <int> <dbl>
## 1 Colombia Americas 2007 72.9 44227550 7007.
## 2 Comoros Africa 2007 65.2 710960 986.
## 3 Congo, Dem. Rep. Africa 2007 46.5 64606759 278.
## 4 Congo, Rep. Africa 2007 55.3 3800610 3633.
## 5 Costa Rica Americas 2007 78.8 4133884 9645.
## 6 Cote d'Ivoire Africa 2007 48.3 18013409 1545.
stringr::str_count que se puede utilizar potencialmente con dplyr::summarizegapminder %>%
filter(year == max(year)) %>%
# Número de paises en el que su nombre termina con una vocal
# en el último año
summarize(pais_termina_vocal = sum(str_count(string = country, pattern = "[aeiou]$")))## # A tibble: 1 x 1
## pais_termina_vocal
## <int>
## 1 77
stringr::str_count con dplyr::mutategapminder %>%
filter(year == max(year)) %>%
# Número de vocales que tiene el nombre de cada país en el
# último año
mutate(pais_vocales = str_count(string = country, pattern = "[AaEeIiOoUu]")) %>%
# Escogemos los 3 primeros países cuyo nombre tiene más vocales
# Se incluyen empates: with_ties = TRUE
slice_max(order_by = pais_vocales,
n = 3,
with_ties = TRUE)## # A tibble: 4 x 7
## country continent year lifeExp pop gdpPercap pais_vocales
## <fct> <fct> <int> <dbl> <int> <dbl> <int>
## 1 Equatorial Guinea Africa 2007 51.6 5.51e5 12154. 10
## 2 Bosnia and Herzegovina Europe 2007 74.9 4.55e6 7446. 9
## 3 Central African Republic Africa 2007 44.7 4.37e6 706. 8
## 4 Sao Tome and Principe Africa 2007 65.5 2.00e5 1598. 8
Se pueden extraer las coincidencias identificadas con stringr::str_extract
stringr::str_extract extrae la primera coincidencia por lo que si se requieren todas las coincidencias se debera utilizar stringr::str_extract_all
stringr::str_extract_all por defecto se obtiene una lista y con el argumento simplify = TRUE se obtiene una matriz con las coincidencias más cortas expandidas hasta el largo de las más extensasgapminder::gapminder %>%
# Extraer loss dos primeros caracteres de los
# nombres de los países en el último año
filter(year == max(year)) %>%
mutate(dos_primeros = str_extract(string = country, pattern = "^..")) %>%
slice(1:5) %>%
select(country, dos_primeros)## # A tibble: 5 x 2
## country dos_primeros
## <fct> <chr>
## 1 Afghanistan Af
## 2 Albania Al
## 3 Algeria Al
## 4 Angola An
## 5 Argentina Ar
Las transformaciones usuales están representadas en las siguientes funciones
stringr::str_to_lower: cadenas de caracteres a minúsculasstringr::str_to_upper: cadenas de caracteres a mayúsculasstringr::str_to_title: cadenas de caracteres a un formato de títuloUna transformación más general se logra a través de stringr::str_replace y stringr::str_replace_all
En este caso los argumentos son:
stringpatternreplacementgapminder::gapminder %>%
filter(year == max(year)) %>%
# cambiar mayúsculas por minúsculas
mutate(country = str_to_lower(country),
# eliminar cualquier caracter diferente
# a letras minúscula
## Por ejemplo . ' o ,
country = str_replace_all(string = country,
pattern = "[^a-z ]",
replacement = "")) %>%
# mostrar ultimas 5 filas
slice_tail(n = 5)## # A tibble: 5 x 6
## country continent year lifeExp pop gdpPercap
## <chr> <fct> <int> <dbl> <int> <dbl>
## 1 vietnam Asia 2007 74.2 85262356 2442.
## 2 west bank and gaza Asia 2007 73.4 4018332 3025.
## 3 yemen rep Asia 2007 62.7 22211743 2281.
## 4 zambia Africa 2007 42.4 11746035 1271.
## 5 zimbabwe Africa 2007 43.5 12311143 470.
A parte de la función stringr::str_c existe una función util stringr::str_glue que es similar a lo que se conocer como Literal String Interpolation (f"") en Python
set.seed(123)
data <- gapminder::gapminder %>%
filter(year == max(year)) %>%
slice_sample(n = 10) %>%
mutate(label_text = str_glue("País: {country}
Año: {year}
PIB per-capita: {round(gdpPercap)}
Esperanza de vida: {lifeExp}")) %>%
select(country, year, lifeExp, gdpPercap, label_text)
data## # A tibble: 10 x 5
## country year lifeExp gdpPercap label_text
## <fct> <int> <dbl> <dbl> <glue>
## 1 Botswana 2007 50.7 12570. "País: Botswana\nAño: 2007\nPIB per-capit…
## 2 Greece 2007 79.5 27538. "País: Greece\nAño: 2007\nPIB per-capita:…
## 3 South Afr… 2007 49.3 9270. "País: South Africa\nAño: 2007\nPIB per-c…
## 4 Ethiopia 2007 52.9 691. "País: Ethiopia\nAño: 2007\nPIB per-capit…
## 5 Zimbabwe 2007 43.5 470. "País: Zimbabwe\nAño: 2007\nPIB per-capit…
## 6 Yemen, Re… 2007 62.7 2281. "País: Yemen, Rep.\nAño: 2007\nPIB per-ca…
## 7 Nepal 2007 63.8 1091. "País: Nepal\nAño: 2007\nPIB per-capita: …
## 8 Netherlan… 2007 79.8 36798. "País: Netherlands\nAño: 2007\nPIB per-ca…
## 9 United St… 2007 78.2 42952. "País: United States\nAño: 2007\nPIB per-…
## 10 New Zeala… 2007 80.2 25185. "País: New Zealand\nAño: 2007\nPIB per-ca…
La función que se utiliza para dividir una cadena de caracteres es stringr::str_split
n se controla el número máximo de elementos que se retornan"Quiero separar esta frase en cada una de sus palabras" %>%
# Podemos realizar análisis de texto de una
# manera "tidy"
str_split(pattern = " ",
n = Inf) %>%
enframe(name = "id_oracion", value = "palabras") %>%
unnest(cols = palabras)## # A tibble: 10 x 2
## id_oracion palabras
## <int> <chr>
## 1 1 Quiero
## 2 1 separar
## 3 1 esta
## 4 1 frase
## 5 1 en
## 6 1 cada
## 7 1 una
## 8 1 de
## 9 1 sus
## 10 1 palabras
El paquete stringr está construido sobre el paquete stringi
stringr es una buena introducción para la manipulación de cadenas de caracteres
Si se requiere utilizar más funcionalidades utilizar stringi